home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 June / PersonalComputerWorld-June2009-CoverdiscCD.iso / Software / Freeware / Firebug 1.3.3 / firebug-1.3.3-fx.xpi / content / firebug / chrome.js < prev    next >
Encoding:
JavaScript  |  2009-02-19  |  38.3 KB  |  1,315 lines

  1. /* See license.txt for terms of usage */
  2.  
  3. var Firebug = null;
  4. var FirebugContext = null;
  5.  
  6. if(!XPCOMUtils)
  7.     throw "Failed to load FBL";
  8.  
  9. (function() { with (XPCOMUtils) {
  10.  
  11. // ************************************************************************************************
  12. // Constants
  13.  
  14. const Cc = Components.classes;
  15. const Ci = Components.interfaces;
  16. const nsIWebNavigation = Ci.nsIWebNavigation;
  17.  
  18. const LOAD_FLAGS_BYPASS_PROXY = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY;
  19. const LOAD_FLAGS_BYPASS_CACHE = nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
  20. const LOAD_FLAGS_NONE = nsIWebNavigation.LOAD_FLAGS_NONE;
  21.  
  22. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  23.  
  24. const panelURL = "chrome://firebug/content/panel.html";
  25.  
  26. const statusCropSize = 20;
  27.  
  28. const positiveZoomFactors = [1, 1.1, 1.2, 1.3, 1.5, 2, 3];
  29. const negativeZoomFactors = [1, 0.95, 0.8, 0.7, 0.5, 0.2, 0.1];
  30.  
  31. // ************************************************************************************************
  32. // Globals
  33.  
  34. var panelBox, panelSplitter, sidePanelDeck, panelBar1, panelBar2, locationList, locationSeparator,
  35.     panelStatus, panelStatusSeparator;
  36.  
  37. var waitingPanelBarCount = 2;
  38.  
  39. var externalMode = (window.location == "chrome://firebug/content/firebug.xul");
  40. var externalBrowser = null;
  41.  
  42. var disabledBox = null;
  43. var disabledHead = null;
  44. var disabledCaption = null;
  45. var enableSiteLink = null;
  46. var enableSystemPagesLink = null;
  47. var enableAlwaysLink = null;
  48.  
  49. // ************************************************************************************************
  50.  
  51. top.FirebugChrome =
  52. {
  53.     window: window,
  54.  
  55.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  56.     // Initialization
  57.  
  58.     panelBarReady: function(panelBar)
  59.     {
  60.         try
  61.         {
  62.             // Wait until all panelBar bindings are ready before initializing
  63.             if (--waitingPanelBarCount == 0)
  64.                 this.initialize();
  65.         }
  66.         catch (exc)
  67.         {
  68.         }
  69.  
  70.     },
  71.  
  72.     initialize: function()
  73.     {
  74.         if (window.arguments)
  75.             var detachArgs = window.arguments[0];
  76.  
  77.         if (!detachArgs)
  78.             detachArgs = {};
  79.  
  80.         if (detachArgs.FBL)
  81.             top.FBL = detachArgs.FBL;
  82.         else
  83.         {
  84.             FBL.initialize();
  85.         }
  86.  
  87.         if (detachArgs.Firebug)
  88.             Firebug = detachArgs.Firebug;
  89.         else
  90.             Firebug.initialize();
  91.  
  92.         panelBox = $("fbPanelBox");
  93.         panelSplitter = $("fbPanelSplitter");
  94.         sidePanelDeck = $("fbSidePanelDeck");
  95.         panelBar1 = $("fbPanelBar1");
  96.         panelBar2 = $("fbPanelBar2");
  97.         locationList = $("fbLocationList");
  98.         locationSeparator = $("fbLocationSeparator");
  99.         panelStatus = $("fbPanelStatus");
  100.         panelStatusSeparator = $("fbStatusSeparator");
  101.  
  102.         var browser1 = panelBar1.browser;
  103.         browser1.addEventListener("load", browser1Loaded, true);
  104.  
  105.         var browser2 = panelBar2.browser;
  106.         browser2.addEventListener("load", browser2Loaded, true);
  107.  
  108.         window.addEventListener("blur", onBlur, true);
  109.     },
  110.  
  111.     /**
  112.      * Called when the UI is ready to be initialized, once the panel browsers are loaded.
  113.      */
  114.     initializeUI: function()
  115.     {
  116.         try {
  117.             if (window.arguments)
  118.                 var detachArgs = window.arguments[0];
  119.  
  120.             if (detachArgs)
  121.             {
  122.                 FirebugContext = detachArgs.context ? detachArgs.context : FirebugContext;
  123.                 externalBrowser = detachArgs.browser;// else undefined
  124.             }
  125.  
  126.             this.applyTextSize(Firebug.textSize);
  127.  
  128.             var doc1 = panelBar1.browser.contentDocument;
  129.             doc1.addEventListener("mouseover", onPanelMouseOver, false);
  130.             doc1.addEventListener("mouseout", onPanelMouseOut, false);
  131.             doc1.addEventListener("mousedown", onPanelMouseDown, false);
  132.             doc1.addEventListener("click", onPanelClick, false);
  133.             panelBar1.addEventListener("selectingPanel", onSelectingPanel, false);
  134.  
  135.             var doc2 = panelBar2.browser.contentDocument;
  136.             doc2.addEventListener("mouseover", onPanelMouseOver, false);
  137.             doc2.addEventListener("mouseout", onPanelMouseOut, false);
  138.             doc2.addEventListener("click", onPanelClick, false);
  139.             doc2.addEventListener("mousedown", onPanelMouseDown, false);
  140.             panelBar2.addEventListener("selectPanel", onSelectedSidePanel, false);
  141.  
  142.             locationList.addEventListener("selectObject", onSelectLocation, false);
  143.  
  144.             $("fbLargeCommandLine").addEventListener('focus', onCommandLineFocus, true);
  145.             $("fbCommandLine").addEventListener('focus', onCommandLineFocus, true);
  146.  
  147.             for (var i = 0; i < Firebug.panelTypes.length; ++i)
  148.             {
  149.                 var panelType = Firebug.panelTypes[i];
  150.                 if (!panelType.prototype.parentPanel)
  151.                     panelBar1.addTab(panelType);
  152.             }
  153.  
  154.             if (externalMode)
  155.                 this.attachBrowser(externalBrowser, FirebugContext);
  156.             else
  157.                 Firebug.initializeUI(detachArgs);
  158.  
  159.         } catch (exc) {
  160.             FBTrace.dumpProperties("chrome.initializeUI fails", exc);
  161.         }
  162.  
  163.     },
  164.  
  165.     shutdown: function()
  166.     {
  167.         var doc1 = panelBar1.browser.contentDocument;
  168.         doc1.removeEventListener("mouseover", onPanelMouseOver, false);
  169.         doc1.removeEventListener("mouseout", onPanelMouseOut, false);
  170.         doc1.removeEventListener("mousedown", onPanelMouseDown, false);
  171.         doc1.removeEventListener("click", onPanelClick, false);
  172.  
  173.         var doc2 = panelBar2.browser.contentDocument;
  174.         doc2.removeEventListener("mouseover", onPanelMouseOver, false);
  175.         doc2.removeEventListener("mouseout", onPanelMouseOut, false);
  176.         doc2.removeEventListener("mousedown", onPanelMouseDown, false);
  177.         doc2.removeEventListener("click", onPanelClick, false);
  178.  
  179.         locationList.removeEventListener("selectObject", onSelectLocation, false);
  180.  
  181.         window.removeEventListener("blur", onBlur, true);
  182.  
  183.         if (externalMode)
  184.             this.detachBrowser(externalBrowser, FirebugContext);
  185.         else
  186.             Firebug.shutdown();
  187.  
  188.     },
  189.  
  190.     updateOption: function(name, value)
  191.     {
  192.         if (panelBar1.selectedPanel)
  193.             panelBar1.selectedPanel.updateOption(name, value);
  194.         if (panelBar2.selectedPanel)
  195.             panelBar2.selectedPanel.updateOption(name, value);
  196.  
  197.         if (name == "textSize")
  198.             this.applyTextSize(value);
  199.     },
  200.  
  201.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  202.  
  203.     attachBrowser: function(browser, context)  // XXXjjb context == (FirebugContext || null)  and externalMode == true
  204.     {
  205.         if (externalMode)
  206.         {
  207.             browser.detached = true;
  208.             browser.originalChrome = browser.chrome;
  209.             browser.chrome = this;
  210.         }
  211.  
  212.         if (context)
  213.         {
  214.             if (externalMode)
  215.                 context.externalChrome = this;
  216.  
  217.             context.reattach(this);
  218.         }
  219.  
  220.         if (context == FirebugContext)
  221.         {
  222.             Firebug.reattachContext(browser, context);
  223.  
  224.             this.syncPanel();
  225.  
  226.             if (!externalMode)
  227.                 Firebug.syncBar(true);
  228.         }
  229.     },
  230.  
  231.     detachBrowser: function(browser, context)
  232.     {
  233.         if (context)
  234.         {
  235.             delete context.externalChrome;
  236.             delete context.detached;
  237.         }
  238.  
  239.         browser.chrome = browser.originalChrome;
  240.         delete browser.showFirebug;
  241.         delete browser.detached;
  242.         delete browser.originalChrome;
  243.  
  244.         if (browser && browser.chrome)
  245.             browser.chrome.attachBrowser(browser, context);
  246.     },
  247.  
  248.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  249.  
  250.     getCurrentBrowser: function()
  251.     {
  252.         return externalBrowser ? externalBrowser : Firebug.tabBrowser.selectedBrowser;
  253.     },
  254.  
  255.     getCurrentURI: function()
  256.     {
  257.         try
  258.         {
  259.             if (externalBrowser)
  260.                 return externalBrowser.currentURI;
  261.             else
  262.                 return Firebug.tabBrowser.currentURI;
  263.         }
  264.         catch (exc)
  265.         {
  266.             return null;
  267.         }
  268.     },
  269.  
  270.     getBrowserURI: function(context)
  271.     {
  272.         try
  273.         {
  274.             if (externalBrowser)
  275.                 return externalBrowser.currentURI;
  276.             if (context && context.browser)
  277.                 return context.browser.currentURI;
  278.         }
  279.         catch (exc)
  280.         {
  281.             return null;
  282.         }
  283.     },
  284.  
  285.     getPanelDocument: function(panelType)
  286.     {
  287.         if (!panelType.prototype.parentPanel)
  288.             return panelBar1.browser.contentDocument;
  289.         else
  290.             return panelBar2.browser.contentDocument;
  291.     },
  292.  
  293.     getPanelBrowser: function(panel)
  294.     {
  295.         if (!panel.parentPanel)
  296.             return panelBar1.browser;
  297.         else
  298.             return panelBar2.browser;
  299.     },
  300.  
  301.     savePanels: function()
  302.     {
  303.         var path = this.writePanels(panelBar1.browser.contentDocument);
  304.         $("fbStatusText").setAttribute("value", path);
  305.     },
  306.  
  307.     writePanels: function(doc)
  308.     {
  309.         var serializer = new XMLSerializer();
  310.         var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
  311.                .createInstance(Components.interfaces.nsIFileOutputStream);
  312.         var file = Components.classes["@mozilla.org/file/directory_service;1"]
  313.            .getService(Components.interfaces.nsIProperties)
  314.            .get("TmpD", Components.interfaces.nsIFile);
  315.         file.append("firebug");   // extensions sub-directory
  316.         file.append("panelSave.html");
  317.         file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
  318.         foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0);   // write, create, truncate
  319.         serializer.serializeToStream(doc, foStream, "");   // rememeber, doc is the DOM tree
  320.         foStream.close();
  321.         return file.path;
  322.     },
  323.  
  324.  
  325.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  326.  
  327.     close: function()
  328.     {
  329.         window.close();
  330.     },
  331.  
  332.     focus: function()
  333.     {
  334.         window.focus();
  335.     },
  336.  
  337.     isFocused: function()
  338.     {
  339.         var winMediator = CCSV("@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
  340.  
  341.         return winMediator.getMostRecentWindow(null) == window;
  342.     },
  343.  
  344.     reload: function(skipCache)
  345.     {
  346.         var reloadFlags = skipCache
  347.             ? LOAD_FLAGS_BYPASS_PROXY | LOAD_FLAGS_BYPASS_CACHE
  348.             : LOAD_FLAGS_NONE;
  349.  
  350.         var browser = this.getCurrentBrowser();
  351.         browser.firebugReload = true;
  352.         browser.webNavigation.reload(reloadFlags);
  353.     },
  354.  
  355.     gotoPreviousTab: function()
  356.     {
  357.         if (FirebugContext.previousPanelName)
  358.             this.selectPanel(FirebugContext.previousPanelName);
  359.     },
  360.  
  361.     getNextObject: function(reverse)
  362.     {
  363.         var panel = FirebugContext.getPanel(FirebugContext.panelName);
  364.         if (panel)
  365.         {
  366.             var item = panelStatus.getItemByObject(panel.selection);
  367.             if (item)
  368.             {
  369.                 if (reverse)
  370.                     item = item.previousSibling ? item.previousSibling.previousSibling : null;
  371.                 else
  372.                     item = item.nextSibling ? item.nextSibling.nextSibling : null;
  373.  
  374.                 if (item)
  375.                     return item.repObject;
  376.             }
  377.         }
  378.     },
  379.  
  380.     gotoNextObject: function(reverse)
  381.     {
  382.         var nextObject = this.getNextObject(reverse);
  383.         if (nextObject)
  384.             this.select(nextObject);
  385.         else
  386.             beep();
  387.     },
  388.  
  389.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  390.     // Panels
  391.  
  392.     navigate: function(object, panelName, sidePanelName)
  393.     {
  394.         var panel;
  395.         if (panelName || sidePanelName)
  396.             panel = this.selectPanel(panelName, sidePanelName);
  397.         else
  398.             panel = this.getSelectedPanel();
  399.  
  400.         if (panel)
  401.             panel.navigate(object);
  402.     },
  403.  
  404.     select: function(object, panelName, sidePanelName, forceUpdate)
  405.     {
  406.         var bestPanelName = getBestPanelName(object, FirebugContext, panelName);
  407.         var panel = this.selectPanel(bestPanelName, sidePanelName, true);
  408.         if (panel)
  409.             panel.select(object, forceUpdate);
  410.     },
  411.  
  412.     selectPanel: function(panelName, sidePanelName, noRefresh)
  413.     {
  414.         if (panelName && sidePanelName)
  415.             FirebugContext.sidePanelNames[panelName] = sidePanelName;
  416.  
  417.         return panelBar1.selectPanel(panelName, false, noRefresh);
  418.     },
  419.  
  420.     selectSidePanel: function(panelName)
  421.     {
  422.         return panelBar2.selectPanel(panelName);
  423.     },
  424.  
  425.     clearPanels: function()
  426.     {
  427.         panelBar1.hideSelectedPanel();
  428.         panelBar1.selectedPanel = null;
  429.         panelBar2.selectedPanel = null;
  430.     },
  431.  
  432.     getSelectedPanel: function()
  433.     {
  434.         return panelBar1.selectedPanel;
  435.     },
  436.  
  437.     getSelectedSidePanel: function()
  438.     {
  439.         return panelBar2.selectedPanel;
  440.     },
  441.  
  442.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  443.     // Location interface provider for binding.xml panelFileList
  444.  
  445.     getLocationProvider: function()
  446.     {
  447.         return function getSelectedPanelFromCurrentContext()
  448.         {
  449.             return FirebugContext.chrome.getSelectedPanel();  // panels provide location, use the selected panel
  450.         }
  451.      },
  452.  
  453.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  454.     // UI Synchronization
  455.  
  456.     showContext: function(browser, context)
  457.     {
  458.         if (context)
  459.         {
  460.             FirebugContext = context;  // the other place the FirebugContext is set is in firebug.js
  461.  
  462.             if (externalBrowser || (context.browser && context.browser.showFirebug) )
  463.                 this.syncPanel();
  464.         }
  465.     },
  466.  
  467.     hidePanel: function()
  468.     {
  469.         if (panelBar1.selectedPanel)
  470.             panelBar1.hideSelectedPanel()
  471.  
  472.         if (panelBar2.selectedPanel)
  473.             panelBar2.hideSelectedPanel()
  474.     },
  475.  
  476.     syncPanel: function()
  477.     {
  478.         panelStatus.clear();
  479.  
  480.         if (FirebugContext)
  481.         {
  482.             var panelName = FirebugContext.panelName
  483.                 ? FirebugContext.panelName
  484.                 : Firebug.defaultPanelName;
  485.  
  486.             // Make HTML panel the default panel, which is displayed
  487.             // to the user the very first time.
  488.             if (!panelName || !Firebug.getPanelType(panelName))
  489.                 panelName = "html";
  490.  
  491.             this.syncMainPanels();
  492.             panelBar1.selectPanel(panelName, true);
  493.         }
  494.         else
  495.         {
  496.             panelBar1.selectPanel(null, true);
  497.         }
  498.  
  499.         if (externalBrowser)
  500.             this.syncTitle();
  501.     },
  502.  
  503.     syncMainPanels: function()
  504.     {
  505.         var panelTypes = Firebug.getMainPanelTypes(FirebugContext);
  506.         panelBar1.updatePanels(panelTypes);
  507.     },
  508.  
  509.     syncSidePanels: function()
  510.     {
  511.         var panelTypes = Firebug.getSidePanelTypes(FirebugContext, panelBar1.selectedPanel);
  512.         panelBar2.updatePanels(panelTypes);
  513.  
  514.         if (FirebugContext && FirebugContext.sidePanelNames)
  515.         {
  516.             var sidePanelName = FirebugContext.sidePanelNames[FirebugContext.panelName];
  517.             sidePanelName = getBestSidePanelName(sidePanelName, panelTypes);
  518.             panelBar2.selectPanel(sidePanelName, true);
  519.         }
  520.         else
  521.             panelBar2.selectPanel(null);
  522.  
  523.         sidePanelDeck.selectedPanel = panelBar2;
  524.         FBL.collapse(sidePanelDeck, !panelBar2.selectedPanel);
  525.         FBL.collapse(panelSplitter, !panelBar2.selectedPanel);
  526.     },
  527.  
  528.     syncTitle: function()
  529.     {
  530.         if (FirebugContext)
  531.         {
  532.             var win = FirebugContext.window;
  533.             var title = win.document.title;
  534.             if (!title)
  535.                 title = win.location.href;
  536.  
  537.             window.document.title = FBL.$STRF("WindowTitle", [title]);
  538.         }
  539.         else
  540.             window.document.title = FBL.$STR("Firebug");
  541.     },
  542.  
  543.     focusLocationList: function()
  544.     {
  545.         locationList.showPopup();
  546.     },
  547.  
  548.     syncLocationList: function()
  549.     {
  550.         var panel = panelBar1.selectedPanel;
  551.         if (panel && panel.location)
  552.         {
  553.             locationList.location = panel.location;
  554.             FBL.collapse(locationSeparator, false);
  555.             FBL.collapse(locationList, false);
  556.         }
  557.         else
  558.         {
  559.             FBL.collapse(locationSeparator, true);
  560.             FBL.collapse(locationList, true);
  561.         }
  562.     },
  563.  
  564.     clearStatusPath: function()
  565.     {
  566.         panelStatus.clear();
  567.     },
  568.  
  569.     syncStatusPath: function()
  570.     {
  571.         var panel = panelBar1.selectedPanel;
  572.         if (!panel)
  573.         {
  574.             panelStatus.clear();
  575.         }
  576.         else
  577.         {
  578.             var path = panel.getObjectPath(panel.selection);
  579.             if (!path || !path.length)
  580.             {
  581.                 FBL.hide(panelStatusSeparator, true);
  582.                 panelStatus.clear();
  583.             }
  584.             else
  585.             {
  586.                 FBL.hide(panelStatusSeparator, false);
  587.  
  588.                 if (panel.name != panelStatus.lastPanelName)
  589.                     panelStatus.clear();
  590.  
  591.                 panelStatus.lastPanelName = panel.name;
  592.  
  593.                 // If the object already exists in the list, just select it and keep the path
  594.                 var selection = panel.selection;
  595.                 var existingItem = panelStatus.getItemByObject(panel.selection);
  596.                 if (existingItem)
  597.                     panelStatus.selectItem(existingItem);
  598.                 else
  599.                 {
  600.                     panelStatus.clear();
  601.  
  602.                     for (var i = 0; i < path.length; ++i)
  603.                     {
  604.                         var object = path[i];
  605.  
  606.                         var rep = Firebug.getRep(object);
  607.                         var objectTitle = rep.getTitle(object, FirebugContext);
  608.                         var title = FBL.cropString(objectTitle, statusCropSize);
  609.                         panelStatus.addItem(title, object, rep, panel.statusSeparator);
  610.                     }
  611.  
  612.                     panelStatus.selectObject(panel.selection);
  613.                 }
  614.             }
  615.         }
  616.     },
  617.  
  618.     toggleOrient: function()
  619.     {
  620.         panelSplitter.orient = panelBox.orient
  621.             = panelBox.orient == "vertical" ? "horizontal" : "vertical";
  622.         var option = $('menu_toggleOrient').getAttribute("option");
  623.         Firebug.setPref(Firebug.prefDomain, option, panelBox.orient != "vertical");
  624.     },
  625.  
  626.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  627.  
  628.     addTab: function(context, url, title, parentPanel)
  629.     {
  630.         context.addPanelType(url, title, parentPanel);
  631.         if (context == FirebugContext)
  632.         {
  633.             if (parentPanel)
  634.             {
  635.                 var currentPanel = this.getSelectedPanel();
  636.                 if (currentPanel && parentPanel == currentPanel.name)
  637.                     this.syncSidePanels();
  638.             }
  639.             else
  640.             {
  641.                 this.syncMainPanels();
  642.             }
  643.         }
  644.     },
  645.  
  646.     removeTab: function(context, url)
  647.     {
  648.         context.removePanelType(url);
  649.     },
  650.  
  651.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  652.  
  653.     getGlobalAttribute: function(id, name)
  654.     {
  655.         var elt = $(id);
  656.         return elt.getAttribute(name);
  657.     },
  658.  
  659.     setGlobalAttribute: function(id, name, value)
  660.     {
  661.         var elt = $(id);
  662.         if (elt)
  663.             elt.setAttribute(name, value);
  664.  
  665.         if (externalMode && FirebugContext && FirebugContext.originalChrome)
  666.             FirebugContext.originalChrome.setGlobalAttribute(id, name, value);
  667.     },
  668.  
  669.  
  670.     setChromeDocumentAttribute: function(id, name, value)
  671.     {
  672.         // Call as context.browser.chrome.setChromeDocumentAttribute() to set attributes in another window.
  673.         var elt = $(id);
  674.         if (elt)
  675.             elt.setAttribute(name, value);
  676.     },
  677.  
  678.     keyCodeListen: function(key, filter, listener, capture)
  679.     {
  680.         if (!filter)
  681.             filter = FBL.noKeyModifiers;
  682.  
  683.         var keyCode = KeyEvent["DOM_VK_"+key];
  684.  
  685.         function fn(event)
  686.         {
  687.             if (event.keyCode == keyCode && (!filter || filter(event)))
  688.             {
  689.                 listener();
  690.                 FBL.cancelEvent(event);
  691.             }
  692.         }
  693.  
  694.         window.addEventListener("keypress", fn, capture);
  695.  
  696.         return [fn, capture];
  697.     },
  698.  
  699.     keyListen: function(ch, filter, listener, capture)
  700.     {
  701.         if (!filter)
  702.             filter = FBL.noKeyModifiers;
  703.  
  704.         var charCode = ch.charCodeAt(0);
  705.  
  706.         function fn(event)
  707.         {
  708.             if (event.charCode == charCode && (!filter || filter(event)))
  709.             {
  710.                 listener();
  711.                 FBL.cancelEvent(event);
  712.             }
  713.         }
  714.  
  715.         window.addEventListener("keypress", fn, capture);
  716.  
  717.         return [fn, capture];
  718.     },
  719.  
  720.     keyIgnore: function(listener)
  721.     {
  722.         window.removeEventListener("keypress", listener[0], listener[1]);
  723.     },
  724.  
  725.     $: function(id)
  726.     {
  727.         return $(id);
  728.     },
  729.  
  730.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  731.  
  732.     applyTextSize: function(value)
  733.     {
  734.         var zoom = value >= 0 ? positiveZoomFactors[value] : negativeZoomFactors[Math.abs(value)];
  735.  
  736.         panelBar1.browser.markupDocumentViewer.textZoom = zoom;
  737.         panelBar2.browser.markupDocumentViewer.textZoom = zoom;
  738.     },
  739.  
  740.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  741.     // UI Event Listeners uilisteners
  742.  
  743.     onPanelNavigate: function(object, panel)
  744.     {
  745.         this.syncLocationList();
  746.     },
  747.  
  748.     onPanelSelect: function(object, panel)
  749.     {
  750.         if (panel == panelBar1.selectedPanel)
  751.         {
  752.             this.syncStatusPath();
  753.  
  754.             var sidePanel = panelBar2.selectedPanel;
  755.             if (sidePanel)
  756.                 sidePanel.select(object);
  757.         }
  758.     },
  759.  
  760.     onApplyDecorator: function(sourceBox) // called on setTimeout after sourceBox viewport has been repainted
  761.     {
  762.     },
  763.     
  764.     onLineSelect: function(sourceLink) // called on scrollTo, passing in the selected line
  765.     {
  766.     },
  767.     //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  768.     
  769.     onOptionsShowing: function(popup)
  770.     {
  771.         for (var child = popup.firstChild; child; child = child.nextSibling)
  772.         {
  773.             if (child.localName == "menuitem")
  774.             {
  775.                 var option = child.getAttribute("option");
  776.                 if (option)
  777.                 {
  778.                     var checked = false;
  779.                     if (option == "profiling")
  780.                         checked = fbs.profiling;
  781.                     else
  782.                         checked = Firebug.getPref(Firebug.prefDomain, option);
  783.  
  784.                     child.setAttribute("checked", checked);
  785.                 }
  786.             }
  787.         }
  788.     },
  789.  
  790.     onToggleOption: function(menuitem)
  791.     {
  792.         var option = menuitem.getAttribute("option");
  793.         var checked = menuitem.getAttribute("checked") == "true";
  794.  
  795.         Firebug.setPref(Firebug.prefDomain, option, checked);
  796.     },
  797.  
  798.     onContextShowing: function(event)
  799.     {
  800.         // xxxHonza: This context-menu support can be used even in separate window, which
  801.         // doesn't contain the FBUI (panels).
  802.         //if (!panelBar1.selectedPanel)
  803.         //    return false;
  804.  
  805.         var popup = $("fbContextMenu");
  806.         var target = document.popupNode;
  807.         var panel = target ? Firebug.getElementPanel(target) : null;
  808.  
  809.         if (!panel)
  810.             panel = panelBar1 ? panelBar1.selectedPanel : null; // the event must be on our chrome not inside the panel
  811.  
  812.         FBL.eraseNode(popup);
  813.  
  814.         if (!this.contextMenuObject && !$("cmd_copy").getAttribute("disabled"))
  815.         {
  816.             var menuitem = FBL.createMenuItem(popup, {label: "Copy"});
  817.             menuitem.setAttribute("command", "cmd_copy");
  818.         }
  819.  
  820.         var object;
  821.         if (this.contextMenuObject)
  822.             object = this.contextMenuObject;
  823.         else if (target && target.ownerDocument == document)
  824.             object = Firebug.getRepObject(target);
  825.         else if (target && panel)
  826.             object = panel.getPopupObject(target);
  827.         else if (target)
  828.             object = Firebug.getRepObject(target); // xxxHonza: What about a node from different document? Is that OK?
  829.  
  830.         this.contextMenuObject = null;
  831.  
  832.         var rep = Firebug.getRep(object);
  833.         var realObject = rep ? rep.getRealObject(object, FirebugContext) : null;
  834.         var realRep = realObject ? Firebug.getRep(realObject) : null;
  835.  
  836.         if (realObject && realRep)
  837.         {
  838.             // 1. Add the custom menu items from the realRep
  839.             var menu = realRep.getContextMenuItems(realObject, target, FirebugContext);
  840.             if (menu)
  841.             {
  842.                 for (var i = 0; i < menu.length; ++i)
  843.                     FBL.createMenuItem(popup, menu[i]);
  844.             }
  845.         }
  846.  
  847.         if (object && rep && rep != realRep)
  848.         {
  849.             // 1. Add the custom menu items from the original rep
  850.             var items = rep.getContextMenuItems(object, target, FirebugContext);
  851.             if (items)
  852.             {
  853.                 for (var i = 0; i < items.length; ++i)
  854.                     FBL.createMenuItem(popup, items[i]);
  855.             }
  856.         }
  857.  
  858.         // 1. Add the custom menu items from the panel
  859.         if (panel)
  860.         {
  861.             var items = panel.getContextMenuItems(realObject, target);
  862.             if (items)
  863.             {
  864.                 for (var i = 0; i < items.length; ++i)
  865.                     FBL.createMenuItem(popup, items[i]);
  866.             }
  867.         }
  868.  
  869.         // 2. Add the inspect menu items
  870.         if (realObject && rep && rep.inspectable)
  871.         {
  872.             var separator = null;
  873.  
  874.             var items = this.getInspectMenuItems(realObject);
  875.             for (var i = 0; i < items.length; ++i)
  876.             {
  877.                 if (popup.firstChild && !separator)
  878.                     separator = FBL.createMenuSeparator(popup);
  879.  
  880.                 FBL.createMenuItem(popup, items[i]);
  881.             }
  882.         }
  883.  
  884.         if (!popup.firstChild)
  885.             return false;
  886.     },
  887.  
  888.     onEditorsShowing: function(popup)
  889.     {
  890.         var editors = Firebug.registeredEditors;
  891.         if ( editors.length > 0 )
  892.         {
  893.             var lastChild = popup.lastChild;
  894.             FBL.eraseNode(popup);
  895.             var disabled = (!FirebugContext);
  896.             for( var i = 0; i < editors.length; ++i )
  897.             {
  898.                 if (editors[i] == "-")
  899.                 {
  900.                     FBL.createMenuItem(popup, "-");
  901.                     continue;
  902.                 }
  903.                 var item = {label: editors[i].label, image: editors[i].image,
  904.                                 nol10n: true, disabled: disabled };
  905.                 var menuitem = FBL.createMenuItem(popup, item);
  906.                 menuitem.setAttribute("command", "cmd_openInEditor");
  907.                 menuitem.value = editors[i].id;
  908.             }
  909.             FBL.createMenuItem(popup, "-");
  910.             popup.appendChild(lastChild);
  911.         }
  912.     },
  913.  
  914.     getInspectMenuItems: function(object)
  915.     {
  916.         var items = [];
  917.  
  918.         // Domplate (+ support for context menus) can be used even in separate
  919.         // windows when FirebugContext doesn't have to be defined.
  920.         if (!FirebugContext)
  921.             return items;
  922.  
  923.         for (var i = 0; i < Firebug.panelTypes.length; ++i)
  924.         {
  925.             var panelType = Firebug.panelTypes[i];
  926.             if (!panelType.prototype.parentPanel
  927.                 && panelType.prototype.name != FirebugContext.panelName
  928.                 && panelSupportsObject(panelType, object))
  929.             {
  930.                 var panelName = panelType.prototype.name;
  931.  
  932.                 var title = Firebug.getPanelTitle(panelType);
  933.                 var label = FBL.$STRF("InspectInTab", [title]);
  934.  
  935.                 var command = bindFixed(this.select, this, object, panelName);
  936.                 items.push({label: label, command: command, nol10n: true});
  937.             }
  938.         }
  939.  
  940.         return items;
  941.     },
  942.  
  943.     onTooltipShowing: function(event)
  944.     {
  945.         // xxxHonza: This tooltip support can be used even in separate window, which
  946.         // doesn't contain the FBUI (panels).
  947.         //if (!panelBar1.selectedPanel)
  948.         //    return false;
  949.  
  950.         var tooltip = $("fbTooltip");
  951.         var target = document.tooltipNode;
  952.  
  953.         var panel = target ? Firebug.getElementPanel(target) : null;
  954.  
  955.         var object;
  956.         if (this.contextMenuObject)
  957.             object = this.contextMenuObject;
  958.         else if (target && target.ownerDocument == document)
  959.             object = Firebug.getRepObject(target);
  960.         else if (panel)
  961.             object = panel.getTooltipObject(target);
  962.  
  963.         var rep = object ? Firebug.getRep(object) : null;
  964.         object = rep ? rep.getRealObject(object, FirebugContext) : null;
  965.         rep = object ? Firebug.getRep(object) : null;
  966.  
  967.         if (object && rep)
  968.         {
  969.             var label = rep.getTooltip(object, FirebugContext);
  970.             if (label)
  971.             {
  972.                 tooltip.setAttribute("label", label);
  973.                 return true;
  974.             }
  975.         }
  976.  
  977.         if (target.hasAttribute("title"))
  978.         {
  979.             tooltip.setAttribute("label", target.getAttribute("title"));
  980.             return true;
  981.         }
  982.  
  983.         return false;
  984.     },
  985.  
  986.     openAboutDialog: function()
  987.     {
  988.         var extensionManager = CCSV("@mozilla.org/extensions/manager;1", "nsIExtensionManager");
  989.         openDialog("chrome://mozapps/content/extensions/about.xul", "",
  990.             "chrome,centerscreen,modal", "urn:mozilla:item:firebug@software.joehewitt.com", extensionManager.datasource);
  991.     }
  992. };
  993.  
  994. // ************************************************************************************************
  995. // Local Helpers
  996.  
  997. function panelSupportsObject(panelType, object)
  998. {
  999.     if (panelType)
  1000.     {
  1001.         try {
  1002.             // This tends to throw exceptions often because some objects are weird
  1003.             return panelType.prototype.supportsObject(object)
  1004.         } catch (exc) {}
  1005.     }
  1006.  
  1007.     return 0;
  1008. }
  1009.  
  1010. function getBestPanelName(object, context, panelName)
  1011. {
  1012.     if (!panelName)
  1013.         panelName = context.panelName;
  1014.  
  1015.     // Check if the suggested panel name supports the object, and if so, go with it
  1016.     if (panelName)
  1017.     {
  1018.         panelType = Firebug.getPanelType(panelName);
  1019.         if (panelSupportsObject(panelType, object))
  1020.             return panelType.prototype.name;
  1021.     }
  1022.  
  1023.     // The suggested name didn't pan out, so search for the panel type with the
  1024.     // most specific level of support
  1025.  
  1026.     var bestLevel = 0;
  1027.     var bestPanel = null;
  1028.  
  1029.     for (var i = 0; i < Firebug.panelTypes.length; ++i)
  1030.     {
  1031.         var panelType = Firebug.panelTypes[i];
  1032.         if (!panelType.prototype.parentPanel)
  1033.         {
  1034.             var level = panelSupportsObject(panelType, object);
  1035.             if (!bestLevel || (level && (level > bestLevel) ))
  1036.             {
  1037.                 bestLevel = level;
  1038.                 bestPanel = panelType;
  1039.             }
  1040.         }
  1041.     }
  1042.  
  1043.     return bestPanel ? bestPanel.prototype.name : null;
  1044. }
  1045.  
  1046. function getBestSidePanelName(sidePanelName, panelTypes)
  1047. {
  1048.     if (sidePanelName)
  1049.     {
  1050.         // Verify that the suggested panel name is in the acceptable list
  1051.         for (var i = 0; i < panelTypes.length; ++i)
  1052.         {
  1053.             if (panelTypes[i].prototype.name == sidePanelName)
  1054.                 return sidePanelName;
  1055.         }
  1056.     }
  1057.  
  1058.     // Default to the first panel type in the list
  1059.     return panelTypes.length ? panelTypes[0].prototype.name : null;
  1060. }
  1061.  
  1062. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  1063. // Event listeners
  1064.  
  1065. function browser1Loaded()
  1066. {
  1067.     var browser1 = panelBar1.browser;
  1068.     browser1.removeEventListener("load", browser1Loaded, true);
  1069.  
  1070.     browser1Loaded.complete = true;
  1071.  
  1072.     if (browser1Loaded.complete && browser2Loaded.complete)
  1073.         FirebugChrome.initializeUI();
  1074. }
  1075.  
  1076. function browser2Loaded()
  1077. {
  1078.     var browser2 = panelBar2.browser;
  1079.     browser2.removeEventListener("load", browser2Loaded, true);
  1080.  
  1081.     browser2Loaded.complete = true;
  1082.  
  1083.     if (browser1Loaded.complete && browser2Loaded.complete)
  1084.         FirebugChrome.initializeUI();
  1085. }
  1086.  
  1087. function onBlur(event)
  1088. {
  1089.     // XXXjjb this seems like a waste: called continuously to clear possible highlight I guess.
  1090.     Firebug.Inspector.highlightObject(null, FirebugContext);
  1091. }
  1092.  
  1093. function onSelectLocation(event)
  1094. {
  1095.     var location = locationList.repObject;
  1096.     FirebugChrome.navigate(location);
  1097. }
  1098.  
  1099. function onSelectingPanel(event)
  1100. {
  1101.     var panel = panelBar1.selectedPanel;
  1102.     var panelName = panel ? panel.name : null;
  1103.     if (FirebugContext)
  1104.     {
  1105.         FirebugContext.previousPanelName = FirebugContext.panelName;
  1106.         FirebugContext.panelName = panelName;
  1107.  
  1108.         FirebugContext.sidePanelName =
  1109.             FirebugContext.sidePanelNames && panelName in FirebugContext.sidePanelNames
  1110.             ? FirebugContext.sidePanelNames[panelName]
  1111.             : null;
  1112.     }
  1113.  
  1114.     FirebugChrome.syncLocationList();
  1115.     FirebugChrome.syncStatusPath();
  1116.     FirebugChrome.syncSidePanels();
  1117.  
  1118.     var browser = panel ? panel.context.browser : FirebugChrome.getCurrentBrowser();
  1119.     Firebug.showPanel(browser, panel);
  1120. }
  1121.  
  1122. function onSelectedSidePanel(event)
  1123. {
  1124.     var sidePanel = panelBar2.selectedPanel;
  1125.     if (FirebugContext)
  1126.     {
  1127.         var panelName = FirebugContext.panelName;
  1128.         if (panelName)
  1129.         {
  1130.             var sidePanelName = sidePanel ? sidePanel.name : null;
  1131.             FirebugContext.sidePanelNames[panelName] = sidePanelName;
  1132.         }
  1133.         else
  1134.         {
  1135.         }
  1136.     }
  1137.     var panel = panelBar1.selectedPanel;
  1138.     if (panel && sidePanel)
  1139.         sidePanel.select(panel.selection);
  1140.  
  1141.     var browser = sidePanel ? sidePanel.context.browser : FirebugChrome.getCurrentBrowser();
  1142.     Firebug.showSidePanel(browser, sidePanel);
  1143. }
  1144.  
  1145. function onPanelMouseOver(event)
  1146. {
  1147.     var object = Firebug.getRepObject(event.target);
  1148.     if (object)
  1149.     {
  1150.         var realObject = getRealObject(object);
  1151.         if (realObject)
  1152.             Firebug.Inspector.highlightObject(realObject, FirebugContext);
  1153.     }
  1154. }
  1155.  
  1156. function onPanelMouseOut(event)
  1157. {
  1158.     Firebug.Inspector.highlightObject(null);
  1159. }
  1160.  
  1161. function onPanelClick(event)
  1162. {
  1163.     var repNode = Firebug.getRepNode(event.target);
  1164.     if (repNode)
  1165.     {
  1166.         var object = repNode.repObject;
  1167.         var rep = Firebug.getRep(object);
  1168.         var realObject = rep ? rep.getRealObject(object, FirebugContext) : null;
  1169.         var realRep = realObject ? Firebug.getRep(realObject) : rep;
  1170.         if (!realObject)
  1171.             realObject = object;
  1172.  
  1173.         if (FBL.isLeftClick(event))
  1174.         {
  1175.             if (FBL.hasClass(repNode, "objectLink"))
  1176.             {
  1177.                 if (realRep)
  1178.                 {
  1179.                     realRep.inspectObject(realObject, FirebugContext);
  1180.                     FBL.cancelEvent(event);
  1181.                 }
  1182.             }
  1183.         }
  1184.         else if (FBL.isControlClick(event) || FBL.isMiddleClick(event))
  1185.         {
  1186.             if (!realRep || !realRep.browseObject(realObject, FirebugContext))
  1187.             {
  1188.                 if (rep && !(rep != realRep && rep.browseObject(object, FirebugContext)))
  1189.                 {
  1190.                     var panel = Firebug.getElementPanel(event.target);
  1191.                     if (!panel || !panel.browseObject(realObject))
  1192.                         return;
  1193.                 }
  1194.             }
  1195.             FBL.cancelEvent(event);
  1196.         }
  1197.     }
  1198. }
  1199.  
  1200. function onPanelMouseDown(event)
  1201. {
  1202.     if (FBL.isLeftClick(event))
  1203.     {
  1204.         var editable = FBL.getAncestorByClass(event.target, "editable");
  1205.         if (editable)
  1206.         {
  1207.             Firebug.Editor.startEditing(editable);
  1208.             FBL.cancelEvent(event);
  1209.         }
  1210.     }
  1211.     else if (FBL.isMiddleClick(event) && Firebug.getRepNode(event.target))
  1212.     {
  1213.         // Prevent auto-scroll when middle-clicking a rep object
  1214.         FBL.cancelEvent(event);
  1215.     }
  1216. }
  1217.  
  1218. function getRealObject(object)
  1219. {
  1220.     var rep = Firebug.getRep(object);
  1221.     var realObject = rep ? rep.getRealObject(object, FirebugContext) : null;
  1222.     var realRep = realObject ? Firebug.getRep(realObject) : rep;
  1223.     return realObject ? realObject : object;
  1224. }
  1225.  
  1226. function onCommandLineFocus(event)
  1227. {
  1228.     // User has decided to use the command line, but the web page may not have the console if the page has no javascript
  1229.     if (Firebug.Console.isNeededGetReady(FirebugContext, FirebugContext.window))
  1230.     {
  1231.         Firebug.Console.injector.forceConsoleCompilationInPage(FirebugContext, FirebugContext.window);
  1232.  
  1233.     }
  1234.     else  // the page had _firebug so we know that consoleInjected.js compiled and ran. 
  1235.     {
  1236.     }
  1237.  
  1238.     if (FirebugContext && FirebugContext.window && FirebugContext.window.wrappedJSObject && !FirebugContext.window.wrappedJSObject._FirebugCommandLine)
  1239.     {
  1240.         Firebug.CommandLine.isNeededGetReady(FirebugContext);
  1241.     }
  1242.     else
  1243.     {
  1244.     }
  1245.  
  1246. // This is hack for 1.3.1. We need to call this from the consoleInjector. 
  1247. // 1.4+ has this code in a better place.
  1248. top.FirebugChrome.onCommandLineFocus = onCommandLineFocus;
  1249.  
  1250. // ************************************************************************************************
  1251. // Utils (duplicated from lib.js)
  1252.  
  1253. function $(id, doc)
  1254. {
  1255.     if (doc)
  1256.         return doc.getElementById(id);
  1257.     else
  1258.         return document.getElementById(id);
  1259. }
  1260.  
  1261. function cloneArray(array, fn)
  1262. {
  1263.    var newArray = [];
  1264.  
  1265.    for (var i = 0; i < array.length; ++i)
  1266.        newArray.push(array[i]);
  1267.  
  1268.    return newArray;
  1269. }
  1270.  
  1271. function bindFixed()
  1272. {
  1273.     var args = cloneArray(arguments), fn = args.shift(), object = args.shift();
  1274.     return function() { return fn.apply(object, args); }
  1275. }
  1276.  
  1277. }})();
  1278.  
  1279. // ************************************************************************************************
  1280.  
  1281. // XXXjoe This horrible hack works around a focus bug in Firefox which is caused when
  1282. // the HTML Validator extension and Firebug are installed.  It causes the keyboard to
  1283. // behave erratically when typing, and the only solution I've found is to delay
  1284. // the initialization of HTML Validator by overriding this function with a timeout.
  1285. if (top.TidyBrowser)
  1286. {
  1287.     var prev = TidyBrowser.prototype.updateStatusBar;
  1288.     TidyBrowser.prototype.updateStatusBar = function()
  1289.     {
  1290.         var self = this, args = arguments;
  1291.         setTimeout(function()
  1292.         {
  1293.             prev.apply(self, args);
  1294.         });
  1295.     }
  1296. }
  1297.  
  1298. // ************************************************************************************************
  1299.  
  1300. function ddd(text)
  1301. {
  1302.     const consoleService = Components.classes["@mozilla.org/consoleservice;1"].
  1303.         getService(Components.interfaces["nsIConsoleService"]);
  1304.     consoleService.logStringMessage(text + "");
  1305. }
  1306.  
  1307. function dddx()
  1308. {
  1309.     Firebug.Console.logFormatted(arguments);
  1310. }
  1311.  
  1312.  
  1313.  
  1314.